export const typing = () => R.any(R.is(R.__, document.activeElement), [HTMLInputElement, HTMLTextAreaElement]);

export function useShortcutKey() {
  // --- prevent ---
  // - [ ] remove keydown reason

  /** 判断是否需要阻止默认事件，像 F5 不用阻止，该刷新刷新 */
  const preventCondPairs = [[R.T, R.T]];

  function addAllowDefault(pred) {
    preventCondPairs.unshift([pred, R.F]);
  }
  
  const needPrevent = R.cond(preventCondPairs);

  // --- pre conds ---

  /** 条件符合才检测键是否按下 */
  const preConds = [];

  const allowCondPairs = R.allPass(preConds);

  function addPreCond(pred) {
    preConds.push(pred);
  }

  // --- primary ---

  /** @type {[键是否按下, 监听器][]} */
  const keyDownCondPairs = [];

  function listenShortcutKey() {
    // 浏览器快捷键 keydown 触发，故监听 keydown 且视情况调 preventDefault()
    addEventListener('keydown', handleShortcutKey, { once: true });
  };

  function handleShortcutKey(event) {
    // 判断是否需要阻止默认事件，像 F5 不用阻止，该刷新刷新
    // 所有快捷键都满足大前提才调用监听器，比如正在打字或某 Modal 已显示则不调用
    needPrevent(event) && event.preventDefault();
    allowCondPairs() && R.cond(keyDownCondPairs)(event);
    listenShortcutKey();
    // - [ ] keep or once again
    // addEventListener('keyup', listenShortcutKey, { once: true });
  }

  function addShortcutKey(keys, listener, preCond = R.T) {
    // 判断 event.key 和指定的功能键是否按下
    // preCond up
    keyDownCondPairs.push([
      R.allPass([
        event => R.equals(R.toLower(keys[0]), R.toLower(event.key)),
        event => R.compose(
          R.all( ([k, v]) => R.propEq(v, k, event) ),
          R.map( k => [`${ k }Key`, keys.includes(k)] )
        )(['ctrl', 'shift', 'alt', 'meta']),
        preCond
      ]),
      listener
    ]);
  }

  return {
    addAllowDefault,
    addPreCond,
    listenShortcutKey,
    addShortcutKey,
    handleShortcutKey,
  };
}
